/** ***********************************************************************************
* @file         can_par_list.c
* @brief        定义  CAN数据配置信息列表
* @details      主要是用来定义数据传输格式，以及数据接口
* @author       杨小珛
* @date         2021/07/29
* @copyright    北京高知科技有限公司    
* @version      V1.0
* @attention    无
**************************************************************************************/

#include "can_par_list.h"
#include "com_lib.h"
#include "log_task.h"

can_config_index_map_t *can_config_index_map = NULL;     /*CAN参数配置映射表*/
can_recv_data_map_t *can1_recv_data_map = NULL;            /*CAN1接收数据映射表*/
can_recv_data_map_t *can2_recv_data_map = NULL;            /*CAN2接收数据映射表*/

static uint32_t can_config_recv_map_updata( can_recv_infor_t *recv , uint8_t index , uint8_t num );

/** ****************************************************************************
* @remarks       void can_config_par_list_init( void )
* @brief         CAN 参数配置表初始化
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
void can_config_par_list_init( void )
{
    /*CAN 配置信息映射表，空间分配*/
    if( can_config_index_map == NULL ) 
    {
        can_config_index_map = (can_config_index_map_t *)gaoz_fibo_malloc( sizeof( can_config_index_map_t ) );
        if( can_config_index_map == NULL )
        {
            while( 1  );
        }
    }
    memset((uint8_t *)can_config_index_map   , 0x00 , sizeof( can_config_index_map_t ) );  
    /*CAN1 数据接收映射表，空间分配*/
    if( can1_recv_data_map == NULL )
    {
        can1_recv_data_map   = (can_recv_data_map_t *)gaoz_fibo_malloc( sizeof( can_recv_data_map_t ) );
        if( can1_recv_data_map == NULL )
        {
            while( 1  );
        }    
    }
    memset((uint8_t *)can1_recv_data_map   , 0x00 , sizeof( can_recv_data_map_t ) );  
    /*CAN2 数据接收映射表，空间分配*/
    if( can2_recv_data_map == NULL )
    {
        can2_recv_data_map   = (can_recv_data_map_t *)gaoz_fibo_malloc( sizeof( can_recv_data_map_t ) );
        if( can2_recv_data_map == NULL )
        {
            while( 1  );
        }  
    }
    memset((uint8_t *)can2_recv_data_map   , 0x00 , sizeof( can_recv_data_map_t ) ); 
    
}

/** ****************************************************************************
* @remarks       void can_config_recv_map_updata( void )
* @brief         CAN 配置表接收映射表数据更新
* @param[in]     *recv CAN 接收信息，index节点，num单元数量
* @param[out]    无
* @return        pdPASS 成功，pdFAIL失败
* @attention     无
*******************************************************************************/
static uint32_t can_config_recv_map_updata( can_recv_infor_t *recv , uint8_t index , uint8_t num )
{
    uint32_t ret = pdFAIL;
    uint8_t i = 0;
    can_recv_data_map_t *can_recv_map = NULL;
    
    if( recv == NULL )
    {
        return pdFAIL;
    }
    if(( index >= UNIT_CONTROL_CONFIG_INDEX ) || ( num >= UNIT_CONTROL_CONFIG_NUM ))
    {
        return pdFAIL;
    }
    
    if( recv->channel == 0x01 ) /*CAN1 驱动列表*/
    {
        can_recv_map = can1_recv_data_map;
    }
    else                          /*CAN2 驱动列表*/
    {
        can_recv_map = can2_recv_data_map;
    }
    if( can_recv_map->num >= CAN_RECV_DATA_MAP_LEN ) 
    {
        return pdFAIL;
    }
    for( i = 0 ; i < can_recv_map->num ; i ++ )
    {
        if( can_recv_map->map[i].cid == recv->cid )
        {
            ret = pdPASS;
            break;
        }
    }
    /*MAP 映射表中没有查询到相同的CID ，则增加新的空间数据*/
    if( ret == pdFAIL )
    {
        can_recv_map->map[can_recv_map->num].cid = recv->cid;
        memset((uint8_t *)can_recv_map->map[can_recv_map->num].data , 0x00 , 8 );
        can_recv_map->num++;
        ret = pdPASS;
    }
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t can_config_index_map_init( uint8_t *par , uint16_t len )
* @brief         CAN 参数配置映射表初始化
* @param[in]     *par 参数源地址，size 参数长度
* @param[out]    无
* @return        pdPASS 成功，pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t can_config_index_map_init( uint8_t *par , uint16_t size )
{
    mcu_config_fault_infor_t error_code;
    //uint32_t ret = pdFAIL;
    uint16_t plen = 0;
    uint8_t  num = 0 , uint_num = 0  , index = 0;
    can_config_index_map_t *can_cfg_map = NULL;
    can_dev_infor_t *can_infor = NULL;
    rs232_dev_infor_t *rs232_infor = NULL;
    can_recv_infor_t *can_recv_m = NULL, *can_recv_p = NULL;
    can_send_infor_t *can_send_m = NULL, *can_send_p = NULL;
    port_input_infor_t *port_input_m = NULL, *port_input_p = NULL;
    port_output_infor_t *port_output_m = NULL, *port_output_p = NULL; 
    rs232_recv_infor_t *rs232_recv_m = NULL, *rs232_recv_p = NULL; 
    rs232_send_infor_t *rs232_send_m = NULL, *rs232_send_p = NULL; 
 
    error_code.faule = 0;
    if(( par == NULL ) || ( size == 0 ) || ( size > SYS_CONFIG_MAX_LEN ))
    {
        error_code.err = PORT_CFG_UNKNOW_ERR;
        return error_code.faule;
    }
    
    can_cfg_map = can_config_index_map;
    while( size != plen )
    {
        if( par[plen] == CAN_DEV_CONFIG_ID )                /*CAN驱动配置表*/
        {
            plen += 1;
            index = par[plen];
            plen += 1;
            if( index >= SYS_CONFIG_CAN_MAX_NUM )
            {
                error_code.err = PORT_CFG_CFG_ERR;
                error_code.index = index;
                error_code.cfg = 0;
                error_code.id = CAN_DEV_CONFIG_ID;
                break;
            }
            if( can_cfg_map->dcan_num >= SYS_CONFIG_CAN_MAX_NUM )
            {
                error_code.err = PORT_CFG_CFG_ERR;
                error_code.index = index;
                error_code.cfg = 0;
                error_code.id = CAN_DEV_CONFIG_ID;
                break;
            }
            can_cfg_map->dcan_num ++;
            can_infor = (can_dev_infor_t *)&par[plen];
            memcpy((uint8_t *)&can_cfg_map->dcan[index] ,(uint8_t *)can_infor ,sizeof( can_dev_infor_t ));  
            plen += sizeof( can_dev_infor_t );
        }
        else if( par[plen] == RS232_DEV_CONFIG_ID )         /*RS232串口驱动配置表*/
        {
            plen += 1;
            index = par[plen];
            plen += 1;
            if( index >= SYS_CONFIG_RS232_MAX_NUM )
            {
                error_code.err = PORT_CFG_CFG_ERR;
                error_code.index = index;
                error_code.cfg = 0;
                error_code.id = RS232_DEV_CONFIG_ID;
                break;
            }
            if( can_cfg_map->d232_num >= SYS_CONFIG_RS232_MAX_NUM )
            {
                error_code.err = PORT_CFG_CFG_ERR;
                error_code.index = index;
                error_code.cfg = 0;
                error_code.id = RS232_DEV_CONFIG_ID;
                break;
            }
            can_cfg_map->d232_num ++;
            rs232_infor = (rs232_dev_infor_t *)&par[plen];
            memcpy((uint8_t *)&can_cfg_map->d232[index],(uint8_t *)rs232_infor,sizeof( rs232_dev_infor_t ) );  
            plen += sizeof( rs232_dev_infor_t );
        }
        else if( par[plen] == UNIT_CONTROL_CONFIG_ID )      /*UNIT单元控制配置表*/
        {
            plen += 1;
            index = par[plen];                               
            plen += 1;
            if( index >= UNIT_CONTROL_CONFIG_INDEX )          /*UNIT单元配置表序号*/
            {
                error_code.err = PORT_CFG_CFG_ERR;
                error_code.index = index;
                error_code.cfg = 0;
                error_code.id = UNIT_CONTROL_CONFIG_ID;
                break;
            }
            if( can_cfg_map->punit_num >= SYS_CONFIG_UNIT_MAX_NUM )
            {
                error_code.err = PORT_CFG_CFG_ERR;
                error_code.index = index;
                error_code.cfg = 0;
                error_code.id = UNIT_CONTROL_CONFIG_ID;
                break;
            }
            can_cfg_map->punit_num ++;
            uint_num = par[plen];
            plen += 1;
            if( uint_num > UNIT_CONTROL_CONFIG_NUM )       /*UNIT单元控制模块个数，进行判断*/
            {
                error_code.err = PORT_CFG_CFG_ERR;
                error_code.index = index;
                error_code.cfg = 0;
                error_code.id = UNIT_CONTROL_CONFIG_ID;
                break;
            }
            if( uint_num == 0 )                            /*UNIT单元控制模块个数为0时，此参数无效*/
            {
                /*判断配置表信息是否已经完成*/
                if( size == plen )                 
                {
                    error_code.err = MCU_CFG_SUC;
                    break;
                }
                continue; 
            }
            can_cfg_map->punit[index].num = uint_num;       /*单元控制模块个数*/
        #if 1   /*新增加单元控制模块 周期次数和周期时间*/
            can_cfg_map->punit[index].cnt = par[plen];      /*单元控制模块周期次数 */
            plen += 1;
            if(( can_cfg_map->punit[index].cnt == 0 ) || ( can_cfg_map->punit[index].cnt > 200 ))
            {
                error_code.err = PORT_CFG_CFG_ERR;
                error_code.index = index;
                error_code.cfg = 0;
                error_code.id = UNIT_CONTROL_CONFIG_ID;
                break;
            }
            can_cfg_map->punit[index].period = par[plen] * 256 + par[plen+1];
            plen += 2;
            if( can_cfg_map->punit[index].period > 10000 )
            {
                error_code.err = PORT_CFG_CFG_ERR;
                error_code.index = index;
                error_code.cfg = 0;
                error_code.id = UNIT_CONTROL_CONFIG_ID;
                break;
            }
        #endif
            for( num = 0 ;  num < uint_num ; num ++ )
            {   
                if( par[plen] == UNIT_CONTROL_MOD_RECV_CAN )
                {
                    plen += 1;
                    //can_cfg_map->punit[index].num ++;
                    can_cfg_map->punit[index].format[num].type = UNIT_CONTROL_MOD_RECV_CAN;
                    if( par[plen] != CAN_RECV_CONFIG_ID )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_RECV_CAN;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 1;
                    can_recv_m = ( can_recv_infor_t * )gaoz_fibo_malloc( sizeof( can_recv_infor_t ) );
                    if( can_recv_m == NULL )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_RECV_CAN;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    can_recv_p = ( can_recv_infor_t * )&par[plen];
                    can_recv_m->channel = can_recv_p->channel;
                    can_recv_m->cid = REV_U32( can_recv_p->cid );
                    can_recv_m->type = can_recv_p->type;
                    can_recv_m->sbit = can_recv_p->sbit;
                    can_recv_m->blen = can_recv_p->blen;
                    can_recv_m->resulotion = REV_U32( can_recv_p->resulotion );
                    can_recv_m->offset = REV_U32( can_recv_p->offset );
                    can_recv_m->state = REV_U32( can_recv_p->state );
                    can_cfg_map->punit[index].format[num].config = ( can_recv_infor_t * )can_recv_m;
                    plen += sizeof( can_recv_infor_t );
                    can_cfg_map->punit[index].format[num].time = par[plen] * 256 + par[plen+1];
                    if( can_cfg_map->punit[index].format[num].time >= 5000 )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_RECV_CAN;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 2;
                    /******************填充CAN RECV 映射表*****************************/
                    if( can_config_recv_map_updata( can_recv_m,index,num   ) != pdPASS )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_RECV_CAN;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                }
                else if( par[plen] == UNIT_CONTROL_MOD_SEND_CAN )
                {
                    plen += 1;
                    //can_cfg_map->punit[index].num ++;
                    can_cfg_map->punit[index].format[num].type = UNIT_CONTROL_MOD_SEND_CAN;
                    if( par[plen] != CAN_SEND_CONFIG_ID )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_SEND_CAN;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 1;
                    can_send_m = ( can_send_infor_t * )gaoz_fibo_malloc( sizeof( can_send_infor_t ) );
                    if( can_send_m == NULL )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_SEND_CAN;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    can_send_p = ( can_send_infor_t * )&par[plen];
                    can_send_m->channel = can_send_p->channel;
                    can_send_m->cid = REV_U32( can_send_p->cid );
                    can_send_m->type = can_send_p->type;
                    can_send_m->count = can_send_p->count;
                    can_send_m->time = REV_U16( can_send_p->time );
                    can_send_m->len = can_send_p->len;
                    if(( can_send_m->len == 0 ) || ( can_send_m->len > 8 ))
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_SEND_CAN;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    memcpy((uint8_t *)can_send_m->data ,(uint8_t *)can_send_p->data ,can_send_p->len );
                    can_cfg_map->punit[index].format[num].config = ( can_send_infor_t * )can_send_m;
                    plen += sizeof( can_send_infor_t );
                    can_cfg_map->punit[index].format[num].time = par[plen] * 256 + par[plen+1];
                    if( can_cfg_map->punit[index].format[num].time >= 5000 )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_SEND_CAN;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 2;
                }
                else if( par[plen] == UNIT_CONTROL_MOD_RECV_PORT )
                {
                    plen += 1;
                    //can_cfg_map->punit[index].num ++;
                    can_cfg_map->punit[index].format[num].type = UNIT_CONTROL_MOD_RECV_PORT;
                    if( par[plen] != PORT_INPUT_CONFIG_ID )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_RECV_PORT;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 1;
                    port_input_m = ( port_input_infor_t * )gaoz_fibo_malloc( sizeof( port_input_infor_t ) );
                    if( port_input_m == NULL )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_RECV_PORT;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    port_input_p = ( port_input_infor_t * )&par[plen];
                    port_input_m->port = REV_U16( port_input_p->port );
                    port_input_m->type = port_input_p->type;
                    //port_input_m->count = port_input_p->count;
                    //port_input_m->time = REV_U16( port_input_p->time );
                    port_input_m->resulotion = REV_U32( port_input_p->resulotion );
                    port_input_m->offset = REV_U32( port_input_p->offset );
                    port_input_m->state = REV_U32( port_input_p->state );
                    can_cfg_map->punit[index].format[num].config = ( port_input_infor_t * )port_input_m;
                    plen += sizeof( port_input_infor_t );
                    can_cfg_map->punit[index].format[num].time = par[plen] * 256 + par[plen+1];
                    if( can_cfg_map->punit[index].format[num].time >= 5000 )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_RECV_PORT;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 2;
                }
                else if( par[plen] == UNIT_CONTROL_MOD_SEND_PORT )
                {
                    plen += 1;
                    //can_cfg_map->punit[index].num ++;
                    can_cfg_map->punit[index].format[num].type = UNIT_CONTROL_MOD_SEND_PORT;
                    if( par[plen] != PORT_OUTPUT_CONFIG_ID )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_SEND_PORT;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 1;
                    port_output_m = ( port_output_infor_t * )gaoz_fibo_malloc( sizeof( port_output_infor_t ) );
                    if( port_output_m == NULL )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_SEND_PORT;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    port_output_p = ( port_output_infor_t * )&par[plen];
                    port_output_m->port = REV_U16( port_output_p->port );
                    port_output_m->out = port_output_p->out;
                    port_output_m->count = port_output_p->count;
                    port_output_m->time = REV_U16( port_output_p->time );
                    can_cfg_map->punit[index].format[num].config = ( port_output_infor_t * )port_output_m;
                    plen += sizeof( port_output_infor_t );
                    can_cfg_map->punit[index].format[num].time = par[plen] * 256 + par[plen+1];
                    if( can_cfg_map->punit[index].format[num].time >= 5000 )
                    {  
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_SEND_PORT;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 2;
                }
                else if( par[plen] == UNIT_CONTROL_MOD_RECV_RS232 )
                {
                    plen += 1;
                    //can_cfg_map->punit[index].num ++;
                    can_cfg_map->punit[index].format[num].type = UNIT_CONTROL_MOD_RECV_RS232;
                    if( par[plen] != RS232_RECV_CONFIG_ID )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_RECV_RS232;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 1;
                    rs232_recv_m = ( rs232_recv_infor_t * )gaoz_fibo_malloc( sizeof( rs232_recv_infor_t ) );
                    if( rs232_recv_m == NULL )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_RECV_RS232;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    rs232_recv_p = ( rs232_recv_infor_t * )&par[plen];
                    rs232_recv_m->len = rs232_recv_p->len;
                    if( rs232_recv_m->len > 200 )
                    {
                        rs232_recv_m->len = 200;
                    }
                    memcpy((uint8_t *)rs232_recv_m->data ,(uint8_t *)rs232_recv_p->data ,rs232_recv_p->len );
                    can_cfg_map->punit[index].format[num].config = ( rs232_recv_infor_t * )rs232_recv_m;
                    plen += rs232_recv_p->len + 1;
                    can_cfg_map->punit[index].format[num].time = par[plen] * 256 + par[plen+1];
                    if( can_cfg_map->punit[index].format[num].time >= 5000 )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_RECV_RS232;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 2;
                }
                else if( par[plen] == UNIT_CONTROL_MOD_SEND_RS232 )
                {
                    plen += 1;
                    //can_cfg_map->punit[index].num ++;
                    can_cfg_map->punit[index].format[num].type = UNIT_CONTROL_MOD_SEND_RS232;
                    if( par[plen] != RS232_SEND_CONFIG_ID )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_SEND_RS232;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 1;
                    rs232_send_m = ( rs232_send_infor_t * )gaoz_fibo_malloc( sizeof( rs232_send_infor_t ) );
                    if( rs232_send_m == NULL )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_SEND_RS232;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    rs232_send_p = ( rs232_send_infor_t * )&par[plen];
                    rs232_send_m->count = rs232_send_p->count;
                    rs232_send_m->time = REV_U16( rs232_send_p->time );
                    rs232_send_m->len = rs232_send_p->len;
                    if( rs232_send_m->len > 200 )
                    {
                        rs232_send_m->len = 200;
                    }
                    memcpy((uint8_t *)rs232_send_m->data ,(uint8_t *)rs232_send_p->data ,rs232_send_p->len );
                    can_cfg_map->punit[index].format[num].config = ( rs232_send_infor_t * )rs232_send_m;
                    plen += rs232_send_m->len + 4;
                    can_cfg_map->punit[index].format[num].time = par[plen] * 256 + par[plen+1];
                    if( can_cfg_map->punit[index].format[num].time >= 5000 )
                    {
                        error_code.err = PORT_CFG_CFG_ERR;
                        error_code.index = index;
                        error_code.cfg = UNIT_CONTROL_MOD_SEND_RS232;
                        error_code.id = UNIT_CONTROL_CONFIG_ID;
                        break;
                    }
                    plen += 2;
                }
                else
                {   
                    error_code.err = PORT_CFG_CFG_ERR;
                    error_code.index = index;
                    error_code.cfg = 0xFF;
                    error_code.id = UNIT_CONTROL_CONFIG_ID;
                    break;
                }
            }
            
        }
        else if( par[plen] == DTC_CONTROL_CONFIG_ID )       /*DTC控制配置表*/
        {
            plen += 1;
        }
        else
        {
            error_code.err = PORT_CFG_CFG_ERR;
            error_code.index = index;
            error_code.cfg = 0xFF;
            error_code.id = 0xFF;
            break;
        }
        /*判断配置表信息是否已经完成*/
        if( size == plen )                 
        {
            error_code.err = MCU_CFG_SUC;
        }
    }
    
    return error_code.faule;
}

/** ****************************************************************************
* @remarks       uint32_t can_config_dev_infor_get( uint8_t channel , uint32_t canid )
* @brief         获取CAN配置表驱动
* @param[in]     dev 获取驱动的类型
* @param[out]    *data 数据目标地址
* @return        数据长度
* @attention     无
*******************************************************************************/
uint32_t can_config_dev_infor_get( can_config_dev_type_e dev , uint8_t *data )
{
    uint32_t len = 0, index = 0, num = 0;
    can_config_index_map_t *can_cfg_map = NULL;
    can_dev_infor_t *can_infor = NULL;
    rs232_dev_infor_t *rs232_infor = NULL;
    port_input_infor_t *port_input = NULL;
    port_output_infor_t *port_output = NULL; 
    uint16_t *port_infor =NULL;
    
    can_cfg_map = can_config_index_map;
    if( dev == CAN_DEV )
    {
        for( index = 0 ; index < can_cfg_map->dcan_num ; index ++ )
        {
            can_infor = (can_dev_infor_t *)&data[len];
            can_infor->channel = can_cfg_map->dcan[index].channel;
            can_infor->frame = can_cfg_map->dcan[index].frame;
            can_infor->baudrate = can_cfg_map->dcan[index].baudrate;
            can_infor->mode = can_cfg_map->dcan[index].mode;
            can_infor->type = can_cfg_map->dcan[index].type;
            len += sizeof( can_dev_infor_t );
        }
    }
    else if( dev == RS232_DEV )
    {
        for( index = 0 ; index < can_cfg_map->d232_num ; index ++ )
        {
            rs232_infor = (rs232_dev_infor_t *)&data[len];
            rs232_infor->channel = can_cfg_map->d232[index].channel;
            rs232_infor->baudrate = can_cfg_map->d232[index].baudrate;
            rs232_infor->datalen = can_cfg_map->d232[index].datalen;
            rs232_infor->databit = can_cfg_map->d232[index].databit; 
            rs232_infor->parity = can_cfg_map->d232[index].parity; 
            len += sizeof( rs232_dev_infor_t );
        }
    }
    else if( dev == PORT_DEV )
    {
        for( index = 0 ; index < can_cfg_map->punit_num ; index ++ )
        {
            port_infor = (uint16_t *)&data[len];
            for( num = 0 ; num < can_cfg_map->punit[index].num ; num ++ )
            {
                if( can_cfg_map->punit[index].format[num].type == UNIT_CONTROL_MOD_RECV_PORT )
                {
                    port_input = (port_input_infor_t *)can_cfg_map->punit[index].format[num].config;
                    *port_infor++ = port_input->port;
                    len += sizeof( uint16_t );
                }
                if( can_cfg_map->punit[index].format[num].type == UNIT_CONTROL_MOD_SEND_PORT )
                {
                    port_output = (port_output_infor_t *)can_cfg_map->punit[index].format[num].config;
                    *port_infor++ = port_output->port;
                    len += sizeof( uint16_t );
                }
            }
        }
    }
    
    return len;
}

/** ****************************************************************************
* @remarks       uint32_t can_config_id_infor_get( uint8_t channel , uint32_t canid )
* @brief         CAN配置表ID 获取
* @param[in]     channel 通道 1 CAN1 2 CAN2
* @param[out]    *canid 数据目标地址
* @return        数据长度
* @attention     无
*******************************************************************************/
uint32_t can_config_id_infor_get( uint8_t channel , uint32_t *canid )
{   
    uint8_t i = 0;
    can_recv_data_map_t *can_recv_map = NULL;

    if( canid == NULL )
    {
        return 0;
    }
    if(( channel != 0x01 ) && ( channel != 0x02 ))
    {
        return 0;
    }
    if( channel == 0x01 )              
    {
        can_recv_map = can1_recv_data_map;      /*CAN1 驱动列表*/
    }
    else                                    
    {
        can_recv_map = can2_recv_data_map;      /*CAN2 驱动列表*/
    }
    
    for( i = 0 ; i < can_recv_map->num ; i ++ )
    {
        canid[i] = can_recv_map->map[i].cid;    /*拷贝接收的CAN ID信息*/
    }
    
    return can_recv_map->num;
}

/** ****************************************************************************
* @remarks       uint32_t can_config_data_infor_set( uint8_t channel , uint32_t canid )
* @brief         CAN配置表数据设置
* @param[in]     channel 通道 1 CAN1 2 CAN2 ，canid ，len 数据长度，*data数据源地址
* @param[out]    无
* @return        pdPASS 成功，pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t can_config_data_infor_set( uint8_t channel , uint32_t canid ,uint8_t len, uint8_t *data )
{
    uint8_t i = 0;
    uint32_t ret = pdFAIL;
    can_recv_data_map_t *can_recv_map = NULL;
    
    if(( channel != 0x01 ) && ( channel != 0x02 ))
    {
        return pdFAIL;
    }
    if( canid == 0 )
    {
        return pdFAIL;
    }
    if(( len == 0 ) || len > 8 )
    {
        return pdFAIL;
    }
    if( data == NULL )
    {
        return pdFAIL;
    }

    if( channel == 0x01 )              
    {
        can_recv_map = can1_recv_data_map;      /*CAN1 驱动列表*/
    }
    else                                    
    {
        can_recv_map = can2_recv_data_map;      /*CAN2 驱动列表*/
    }
    
    for( i = 0 ; i < can_recv_map->num ; i ++ )
    {
        if( can_recv_map->map[i].cid == canid )
        {
            memcpy((uint8_t *)can_recv_map->map[i].data , (uint8_t *)data , len  );
            ret = pdPASS;
            break;
        }
    }
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t can_config_data_infor_get(uint8_t channel,uint32_t cid,uint8_t index, uint8_t num, uint8_t *data )
* @brief         CAN配置表数据设置
* @param[in]     channel 通道，index 节点，num 数量,cid 返回CAN ID，，
* @param[out]    *data 返回CAN 数据
* @return        pdPASS 成功，pdFAIL失败
* @attention     无
*******************************************************************************/
uint32_t can_config_data_infor_get(uint8_t channel,uint32_t cid,uint8_t index, uint8_t num, uint8_t *data )
{   
    uint8_t i = 0;
    uint32_t ret = pdFAIL;
    can_recv_data_map_t *can_recv_map = NULL;
    
    if(( channel != 0x01 ) && ( channel != 0x02 ))
    {
        return pdFAIL;
    }
    if(( index >= UNIT_CONTROL_CONFIG_INDEX ) || ( num >= UNIT_CONTROL_CONFIG_NUM ) || ( data == NULL ))
    {
        return pdFAIL;
    }
    
    if( channel == 0x01 )              
    {
        can_recv_map = can1_recv_data_map;      /*CAN1 驱动列表*/
    }
    else                                    
    {
        can_recv_map = can2_recv_data_map;      /*CAN2 驱动列表*/
    }
    
    for( i = 0 ; i < can_recv_map->num ; i ++ )
    {
        if( can_recv_map->map[i].cid == cid )
        {
            memcpy((uint8_t *)data , (uint8_t *)can_recv_map->map[i].data , 8 );
            ret = pdPASS;
            break;
        }
    }
    
    return ret;
}

/** ****************************************************************************
* @remarks       uint32_t can_config_index_format_num_get( uint8_t index )
* @brief         获取CAN UNIT 配置表项目配置数量
* @param[in]     index 项目节点
* @param[out]    无
* @return        获取数据num 数量
* @attention     无
*******************************************************************************/
uint32_t can_config_index_format_num_get( uint8_t index )
{   
    can_config_index_map_t *can_cfg_map = NULL;
    
    if( index >= UNIT_CONTROL_CONFIG_INDEX )
    {
        return 0;
    }
    can_cfg_map = can_config_index_map;
    
    if( index >= can_cfg_map->punit_num ) 
    {
        return 0;
    }
    if( can_cfg_map->punit[index].num > UNIT_CONTROL_CONFIG_NUM )
    {
        return 0;
    }
    
    return can_cfg_map->punit[index].num;
}

/** ****************************************************************************
* @remarks       uint32_t can_config_index_format_get( uint8_t index ,  unit_control_infor_t *format )
* @brief         获取CAN UNIT 配置表项目数据
* @param[in]     index 项目节点
* @param[out]    *format 数据源地址
* @return        获取数据num 数量
* @attention     无
*******************************************************************************/
uint32_t can_config_index_format_get( uint8_t index , unit_control_infor_t *format )
{   
    uint8_t num = 0;
    can_config_index_map_t *can_cfg_map = NULL;
    
    if( index >= UNIT_CONTROL_CONFIG_INDEX )
    {
        return pdFAIL;
    }
    can_cfg_map = can_config_index_map;
    
    if( index >= can_cfg_map->punit_num ) 
    {
        return pdFAIL;
    }
    if( can_cfg_map->punit[index].num > UNIT_CONTROL_CONFIG_NUM )
    {
        return pdFAIL;
    }
    format->num = can_cfg_map->punit[index].num;
    format->cnt = can_cfg_map->punit[index].cnt;
    format->period = can_cfg_map->punit[index].period;
    for( num = 0; num < can_cfg_map->punit[index].num; num++ )
    {   
        format->format[num].type = can_cfg_map->punit[index].format[num].type;
        format->format[num].config = can_cfg_map->punit[index].format[num].config;
        format->format[num].time = can_cfg_map->punit[index].format[num].time;
    }
    
    return pdPASS;
}

/** ****************************************************************************
* @remarks       uint32_t can_config_read_can_signal( can_recv_infor_t *signal,uint8_t *sst, uint8_t *buf, uint8_t *out )
* @brief         读取CAN CFG 单项CAN 信号数值
* @param[in]     *signal CAN 信号配置，*sst数据状态，*buf CAN 数据源地址，长度8个字节。
* @param[out]    *out 数据输出目标地址
* @return        数据长度
* @attention     无
*******************************************************************************/
static uint32_t pow_value( uint8_t n )
{
	uint8_t i = 0;
	uint32_t va = 1;
    
	if( n == 0 )
    {   
        return va;
    }
	for(  i=1 ; i <= n ; i++ )
	{
		va *= 2;
	}
    
	return va;
}
uint32_t can_config_read_can_signal( can_recv_infor_t *signal,uint8_t *sst, uint8_t *buf, uint8_t *out )
{
	uint8_t matrix_buf[64] = {0};
	uint8_t start_bit = 0, i = 0, j = 0, frame = 0, state = 0, size = 0;
    double  fvalue = 0 , resulotion = 0;
    int32_t offset = 0;
    
    if(( signal == NULL ) || ( sst == NULL ) || ( buf == NULL ) || ( out == NULL))
    {
        return 0;
    }
    /******************数据帧格式进行判断************************/
    frame = (uint8_t)( signal->type & 0x0F );
	switch( frame )
	{   
		case CAN_CFG_FORMAT_INTEL:
			start_bit = signal->sbit;
			for(i=0;i<8;i++)
			{
				for(j=0;j<8;j++)
				{
					matrix_buf[i*8+j] = (buf[i]>>j)&0x01;
				}
			}
			break;
		case CAN_CFG_FORMAT_MOTO_LSB:
			start_bit = (((uint8_t)(signal->sbit%8))*2)+56 - signal->sbit;
			for(i=0;i<8;i++)
			{
				for(j=0;j<8;j++)
				{
					matrix_buf[i*8+j] = (buf[7-i]>>j)&0x01;
				}
			}
			break;
		case CAN_CFG_FORMAT_MOTO_MSB:
			start_bit = (((uint8_t)(signal->sbit%8))*2)+56 - signal->sbit;
			start_bit = start_bit - signal->blen +1;
			for(i=0;i<8;i++)
			{
				for(j=0;j<8;j++)
				{
					matrix_buf[i*8+j] = (buf[7-i]>>j)&0x01;
				}
			}
		break;
		default:
            return 0;////invalid format
	}
    /******************数据类型进行判断************************/
    state = (uint8_t)(( signal->type & 0xF0 ) >> 4 );
	switch( state )
	{
        case CAN_CFG_FORMAT_DATA:  /*数据*/
            *sst = CAN_CFG_FORMAT_DATA;
            fvalue = 0;
        	for(  i=0 ; i<signal->blen ;  i++ )
        	{
        		if(matrix_buf[start_bit+i] == 0x01)
        		{
        			fvalue += pow_value(i);
        		}
        	}
        	if( 0 == signal->resulotion )
        	{
        		return 0;
        	}
            resulotion = (float)( signal->resulotion / 1000000.0f );
            if(( signal->offset & 0x80000000) == 0x80000000 )
            {
                offset =(int32_t)( 0 - ( signal->offset & 0x7FFFFFFF ));
            }
            else
            {
                offset =(int32_t)( signal->offset & 0x7FFFFFFF );
            }
        	fvalue = (float)(( fvalue * resulotion ) + offset );
            double_to_bytes( (uint8_t *)out, fvalue );
            size = sizeof( double );  /*数据长度，4个字节*/
        break;
        case CAN_CFG_FORMAT_STATE:    /*状态*/
            *sst = CAN_CFG_FORMAT_STATE;
            fvalue = 0;
            for(  i=0 ; i<signal->blen ;  i++ )
            {
                if( matrix_buf[start_bit+i] == 0x01 )
                {
                    fvalue += pow_value(i);
                }
            }
            /*CAN 状态描述*/
            if(( signal->app0 == fvalue ) && ( signal->app0 != 0xF ))
            {
                *out = 0x00;
            }
            else if(( signal->app1 == fvalue ) && ( signal->app1 != 0xF ))
            {
                *out = 0x01;
            }
            else if(( signal->app2 == fvalue ) && ( signal->app2 != 0xF ))
            {
                *out = 0x02;
            }
            else if(( signal->app3 == fvalue ) && ( signal->app3 != 0xF ))
            {
                *out = 0x03;
            }
            else if(( signal->app4 == fvalue ) && ( signal->app4 != 0xF ))
            {
                *out = 0x04;
            }
            else if(( signal->app5 == fvalue ) && ( signal->app5 != 0xF ))
            {
                *out = 0x05;
            }
            else if(( signal->app6 == fvalue ) && ( signal->app6 != 0xF ))
            {
                *out = 0x06;
            }
            else if(( signal->app7 == fvalue ) && ( signal->app7 != 0xF ))
            {
                *out = 0x07;
            }
            else
            {   
                *out = 0xF;
            }
            size = sizeof( uint8_t );
        break;
        case CAN_CFG_FORMAT_STRING:     /*字符*/
            *sst = CAN_CFG_FORMAT_STRING;
            for(  i=0 ; i<signal->blen ;  i++ )
            {
                if( matrix_buf[start_bit+i] == 0x01 )
                {
                    out[size] += pow_value(i);
                }
                if(( i % 7 ) == 0 )
                {
                    size += 1;
                }
            }
        break;
        default:
            size = 0;
        break;    
    }
    
  	return size;
}

/** ****************************************************************************
* @remarks       uint32_t can_config_read_port_signal( port_input_infor_t *signal,uint8_t *sst, uint16_t data, uint8_t *out )
* @brief         读取PORT CFG 单项信号数值
* @param[in]     *signal PORT信号配置，*sst数据状态，data 数据
* @param[out]    *out 数据输出目标地址
* @return        数据长度
* @attention     无
*******************************************************************************/

#define PORT_CFG_FORMAT_DATA             0x1
#define PORT_CFG_FORMAT_STATE            0x2

uint32_t can_config_read_port_signal( port_input_infor_t *signal,uint8_t *sst, uint16_t data, uint8_t *out )
{
	uint32_t size = 0;
    float fvalue = 0 , resulotion = 0;
    int32_t offset = 0;
    uint16_t vmin = 0, vmax = 0;
    
    if(( signal == NULL ) || ( sst == NULL ) || ( out == NULL))
    {
        return 0;
    }
    if( signal->type == PORT_CFG_FORMAT_DATA )
    {
        *sst = PORT_CFG_FORMAT_DATA;
        resulotion = (float)( signal->resulotion / 1000000.0f );
        if(( signal->offset & 0x80000000) == 0x80000000 )
        {
            offset =(int32_t)( 0 - ( signal->offset & 0x7FFFFFFF ));
        }
        else
        {
            offset =(int32_t)( signal->offset & 0x7FFFFFFF );
        }
        fvalue = (float)(( data * resulotion ) + offset );
        float_to_bytes( (uint8_t *)out, fvalue );
        size = sizeof( float );         /*数据长度，4个字节*/
    }
    else if( signal->type == PORT_CFG_FORMAT_STATE )
    {
        *sst = PORT_CFG_FORMAT_STATE;
        if( signal->st == 0x1 )         /*INPUT*/
        {
            if( signal->app0 == data )
            {
                *out = 0x00;
                size = sizeof( uint8_t );
            }
            else if( signal->app1 == data )
            {
                *out = 0x01;
                size = sizeof( uint8_t );
            }
        }
        else if( signal->st == 0x2 )    /*ADC*/
        {
            resulotion = (float)( signal->resulotion / 1000000.0f );
            if(( signal->offset & 0x80000000) == 0x80000000 )
            {
                offset =(int32_t)( 0 - ( signal->offset & 0x7FFFFFFF ));
            }
            else
            {
                offset =(int32_t)( signal->offset & 0x7FFFFFFF );
            }
            fvalue = (float)(( data * resulotion ) + offset );
            vmin = (uint16_t)(( signal->app0 & 0x00FF ) * 100 );
            vmax = (uint16_t)((( signal->app0 & 0xFF00 ) >> 8 ) * 100 );
            if(( fvalue >= vmin  ) && ( fvalue <= vmax  ))
            {
                *out = 0x00;
                size = sizeof( uint8_t );
            }
            else
            {
                vmin = (uint16_t)(( signal->app1 & 0x00FF ) * 100 );
                vmax = (uint16_t)((( signal->app1 & 0xFF00 ) >> 8 ) * 100 );
                if(( fvalue >= vmin  ) && ( fvalue <= vmax  ))
                {
                    *out = 0x01;
                    size = sizeof( uint8_t );
                }
            }
        }
    }
    
  	return size;
}
